package com.sharer.last.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sharer.last.base.utils.StringUtil;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 提供一些对象有效性校验的方法
 */
public class CheckUtil {

    private static final Class<?>[] BASIC_NUMBER_CLASSES = new Class[]{short.class, int.class, long.class, float.class, double.class};

    /**
     * 判断字符串是否为null
     *
     * @param string
     * @return
     */
    public static boolean isNull(String string) {
        return string == null || "".equals(string.trim())
                || "null".equalsIgnoreCase(string.trim());
    }

    /**
     * 判断字符串有效性
     */
    public static boolean valid(String src) {
        return !(src == null || "".equals(src.trim()));
    }

    /**
     * 判断一组字符串是否有效
     *
     * @param src String
     * @return boolean
     */
    public static boolean valid(String... src) {
        for (String s : src) {
            if (!valid(s)) {
                return false;
            }
        }
        return true;
    }


    /**
     * 判断一个对象是否为空
     */
    public static boolean valid(Object obj) {
        return !(null == obj);
    }

    /**
     * 判断一组对象是否有效
     *
     * @param objects Object...
     * @return boolean
     */
    public static boolean valid(Object... objects) {
        return (objects != null && objects.length != 0);
    }

    /**
     * 判断集合的有效性
     */
    public static boolean valid(Collection col) {
        return !(col == null || col.isEmpty());
    }

    /**
     * 判断一组集合是否有效
     *
     * @param cols Collection...
     * @return boolean
     */
    public static boolean valid(Collection... cols) {
        for (Collection c : cols) {
            if (!valid(c)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断map是否有效
     *
     * @param map Map
     * @return boolean
     */
    public static boolean valid(Map map) {
        return !(map == null || map.isEmpty());
    }

    /**
     * 判断一组map是否有效
     *
     * @param maps 需要判断map
     * @return 是否全部有效
     */
    public static boolean valid(Map... maps) {
        for (Map m : maps) {
            if (!valid(m)) {
                return false;
            }
        }
        return true;
    }


    /**
     * 对象是否不为空(新增)
     *
     * @author fengshuonan
     * @Date 2018/3/18 21:57
     */
    public static boolean isNotEmpty(Object o) {
        return !isEmpty(o);
    }

    /**
     * 对象是否为空
     *
     * @author fengshuonan
     * @Date 2018/3/18 21:57
     */
    public static boolean isEmpty(Object o) {
        if (o == null) {
            return true;
        }
        if (o instanceof String) {
            if (o.toString().trim().equals("")) {
                return true;
            }
        } else if (o instanceof List) {
            if (((List) o).size() == 0) {
                return true;
            }
        } else if (o instanceof Map) {
            if (((Map) o).size() == 0) {
                return true;
            }
        } else if (o instanceof Set) {
            if (((Set) o).size() == 0) {
                return true;
            }
        } else if (o instanceof Object[]) {
            if (((Object[]) o).length == 0) {
                return true;
            }
        } else if (o instanceof int[]) {
            if (((int[]) o).length == 0) {
                return true;
            }
        } else if (o instanceof long[]) {
            if (((long[]) o).length == 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 对象组中是否存在空对象
     *
     * @author fengshuonan
     * @Date 2018/3/18 21:59
     */
    public static boolean isOneEmpty(Object... os) {
        for (Object o : os) {
            if (isEmpty(o)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 对象组中是否全是空对象
     *
     * @author fengshuonan
     * @Date 2018/3/18 21:59
     */
    public static boolean isAllEmpty(Object... os) {
        for (Object o : os) {
            if (!isEmpty(o)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 检查是否为int类型的数据,
     *
     * @param obj
     * @return
     */
    public static boolean isInt(String obj) {
        try {
            Integer.valueOf(obj);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 检查是否为int类型的数据,
     *
     * @param obj
     * @return
     */
    public static boolean isInt(Object obj) {
        try {
            Integer.valueOf(obj.toString());
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 检查是否为Long类型的数据,
     *
     * @param obj
     * @return
     */
    public static boolean isLong(String obj) {
        if (obj == null) {
            return false;
        }
        try {
            Long.valueOf(obj);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 检查否为Long类型的数据,
     *
     * @param obj
     * @return
     */
    public static boolean isLong(Object obj) {
        if (obj == null) {
            return false;
        }
        try {
            Long.valueOf(obj.toString());
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 检查是否为Float类型的数据,
     *
     * @param obj
     * @return
     */
    public static boolean isFloat(String obj) {
        try {
            Float.valueOf(obj);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 检查是否为Float类型的数据,
     *
     * @param obj
     * @return
     */
    public static boolean isFloat(Object obj) {
        try {
            Float.valueOf(obj.toString());
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 检查是否为Double类型的数据,
     *
     * @param obj
     * @return
     */
    public static boolean isDouble(String obj) {
        try {
            Double.valueOf(obj);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 检查是否为Double类型的数据,
     *
     * @param obj
     * @return
     */
    public static boolean isDouble(Object obj) {
        try {
            Double.valueOf(obj.toString());
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 检查是否为Boolean数据
     *
     * @param obj
     * @return
     */
    public static boolean isBoolean(String obj) {
        return (obj != null && (obj.equals("true") || obj.equals("false")));
    }

    /**
     * 检查字符串是否为Boolean数据
     *
     * @param obj
     * @return
     */
    public static boolean isBoolean(Object obj) {
        return (obj != null && (obj.equals("true") || obj.equals("false")));
    }


    /***是否hashMap
     *
     * @param obj
     * @return
     */
    public static boolean isHashMap(Object obj) {
        if (obj instanceof HashMap) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 检查是否为json格式
     *
     * @param str
     * @return
     */
    public static boolean isJson(String str) {
        if (StringUtil.isEmpty(str)) {
            return false;
        }
        try {
            JSONObject jsonStr = JSONObject.parseObject(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean isJsonObject(String str) {
        return isJson(str);
    }

    public static boolean isJsonArray(String str) {
        if (StringUtil.isEmpty(str)) {
            return false;
        }
        try {
            JSONArray jsonStr = JSONObject.parseArray(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 判断value是否是基本数据类型
     *
     * @param value 需要转换的值
     * @author jianggm
     */
    public static boolean isBaseType(Object value) {
        if (value instanceof Number || value instanceof Boolean || value instanceof String) {
            return true;
        }
        return false;
    }

    /**
     * 判断value是否是基本数据类型
     *
     * @param clzz
     * @return
     */
    public static boolean isBaseType(Class<?> clzz) {
        if (clzz.equals(String.class) || clzz.equals(int.class) || clzz.equals(short.class) || clzz.equals(byte.class)
                || clzz.equals(long.class) || clzz.equals(boolean.class) || clzz.equals(Boolean.class) || clzz.equals(float.class)
                || clzz.equals(Float.class) || clzz.equals(double.class) || clzz.equals(Double.class)) {
            return true;
        }
        return false;
    }


    private static boolean isMatch(String regex, String orginal) {
        if (orginal == null || orginal.trim().equals("")) {
            return false;
        }
        Pattern pattern = Pattern.compile(regex);
        Matcher isNum = pattern.matcher(orginal);
        return isNum.matches();
    }

    public static boolean isPositiveInteger(String orginal) {
        return isMatch("^\\+{0,1}[1-9]\\d*", orginal);
    }

    public static boolean isNegativeInteger(String orginal) {
        return isMatch("^-[1-9]\\d*", orginal);
    }

    public static boolean isWholeNumber(String orginal) {
        return isMatch("[+-]{0,1}0", orginal) || isPositiveInteger(orginal) || isNegativeInteger(orginal);
    }

    public static boolean isPositiveDecimal(String orginal) {
        return isMatch("\\+{0,1}[0]\\.[1-9]*|\\+{0,1}[1-9]\\d*\\.\\d*", orginal);
    }

    public static boolean isNegativeDecimal(String orginal) {
        return isMatch("^-[0]\\.[1-9]*|^-[1-9]\\d*\\.\\d*", orginal);
    }

    public static boolean isDecimal(String orginal) {
        return isMatch("[-+]{0,1}\\d+\\.\\d*|[-+]{0,1}\\d*\\.\\d+", orginal);
    }

    public static boolean isRealNumber(String orginal) {
        return isWholeNumber(orginal) || isDecimal(orginal);
    }


    /**
     * 判断是否是数字类型
     *
     * @param obj a {@link Object} object.
     * @return a boolean.
     */
    public static final boolean isNumber(Object obj) {
        if (obj == null) {
            //throw new RuntimeException("object is null.");
            return false;
        }
        if (obj instanceof Number) {
            return true;
        } else {
            for (Class<?> clazz : BASIC_NUMBER_CLASSES) {
                if (obj.getClass().equals(clazz)) {
                    return true;
                }
            }
        }
        return false;
    }

    public static final boolean isNumberStr(String str) {
        try {
            Integer.parseInt(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /***
     * 判断两个数组是否相同 (不考虑顺序)
     * @param array1
     * @param array2
     * @return
     */
    public static boolean isSameArray(String[] array1, String[] array2) {
        Arrays.sort(array1);
        Arrays.sort(array2);
        return Arrays.equals(array1, array2);
    }

    /***
     * 判断两个数组是否包含 array1 是否包含 array2
     * @param array1
     * @param array2
     * @return
     */
    public static boolean isContainArray(String[] array1, String[] array2) {
        Arrays.sort(array1);
        Arrays.sort(array2);
        List<String> list1 = Arrays.asList(array1);
        List<String> list2 = Arrays.asList(array2);
        // 交集 retainAll
        return list1.containsAll(list2);
    }

    /**
     * 是否是日期格式
     * @return
     */
    public static boolean isDate(String obj) {
        try {
            Double.valueOf(obj);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }
}
